#include <core/frame/frame.h>

#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <cstdlib> //std::system
#include <iostream>
#include <string>

namespace bi = boost::interprocess;
using namespace violet;

struct shm_remove {
    shm_remove() {
        bi::shared_memory_object::remove("__violet_frame_shared_memory__");
    }
    ~shm_remove() {
        bi::shared_memory_object::remove("__violet_frame_shared_memory__");
    }
};

int main(int argc, char* argv[]) {
    if (argc == 1) {
        shm_remove remover;
        std::cout << "add data" << std::endl;
        frame::Frame.AddSerialByVec(1, "nihao1", std::vector<uint8_t>{1, 2, 3});
        frame::Frame.AddSerialByVec(2, "nihao2", std::vector<uint8_t>{4, 5, 6});
        frame::Frame.AddSerialByVec(3, "nihao3", std::vector<uint8_t>{7, 8, 9});

        for (const auto& v : frame::Frame.GetSerial(1).Value()) std::cout << (int)v;
        std::cout << "" << std::endl;
        for (const auto& v : frame::Frame.GetSerial(2).Value()) std::cout << (int)v;
        std::cout << "" << std::endl;
        for (const auto& v : frame::Frame.GetSerial(3).Value()) std::cout << (int)v;
        std::cout << "" << std::endl;
        std::cout << "before child" << std::endl;
        auto child_command_line = std::string{argv[0]};
        auto succ               = std::system((child_command_line + std::string{" child "}).c_str());
        std::cout << succ << std::endl;
        std::cout << "before return" << std::endl;
        return succ;
    } else {
        std::cout << "before segment" << std::endl;
        auto segment = bi::managed_shared_memory{bi::open_only, "__violet_frame_shared_memory__"};
        std::cout << "before find" << std::endl;
        auto data = segment
                        .find<bi::map<uint64_t, frame::Serial, std::less<uint64_t>,
                                      bi::allocator<std::pair<const uint64_t, frame::Serial>,
                                                    bi::managed_shared_memory::segment_manager>>>(
                            "__violet_frame_shared_memory_data__")
                        .first;
        std::cout << "before data" << std::endl;

        auto the_serial1 = data->at(1);
        std::cout << "before cout the serial1" << std::endl;
        for (const auto& v : the_serial1.Value()) std::cout << (int)v;
        std::cout << "" << std::endl;

        auto the_serial2 = data->at(2);
        std::cout << "before cout the serial2" << std::endl;
        for (const auto& v : the_serial2.Value()) std::cout << (int)v;
        std::cout << "" << std::endl;

        auto the_serial3 = data->at(3);
        std::cout << "before cout the serial3" << std::endl;
        for (const auto& v : the_serial3.Value()) std::cout << (int)v;
        std::cout << "" << std::endl;

        std::cout << "before child return 0" << std::endl;
        return 0;
    }
}